/**
 @file ctc_dot1ae.h

 @author  Copyright (C) 2011 Centec Networks Inc.  All rights reserved.

 @date 2010-2-4

 @version v2.0

   This file contains all dot1ae related data structure, enum, macro and proto.
*/

#ifndef _CTC_DOT1AE_H_
#define _CTC_DOT1AE_H_
#ifdef __cplusplus
extern "C" {
#endif

/****************************************************************
 *
 * Header Files
 *
 ***************************************************************/
#include "common/include/ctc_const.h"
#include "ctc_field.h"

/****************************************************************
*
* Defines and Macros
*
****************************************************************/
/**
 @defgroup dot1ae DOT1AE
 @{
*/
#define CTC_DOT1AE_KEY_LEN             32               /**< [D2.TM.TMM.AT] 802.1ae key length*/
#define CTC_DOT1AE_SALT_LEN            12               /**< [TM.TMM.AT] 802.1ae SALT length*/
#define CTC_DOT1AE_EVENT_MAX_NUM       32               /**< [TMM.AT] The max num of Dot1ae event for isr call back*/
#define CTC_DOT1AE_REPLAY_WINDOW_MAX_SIZE 0x3fffffff    /**< [TM.TMM.AT] According to the protocal xpn max replay window size */
#define CTC_DOT1AE_FIELD_KEY_NUM       20               /**< [AT] max number of dot1ae hash key field */

/**
 @brief Dot1ae encryption algorithm type
*/
enum ctc_dot1ae_alg_type_e
{
    CTC_DOT1AE_ALG_TYPE_AES,    /**< [D2.TM.TMM.AT] Aes encrypt algorithm*/
    CTC_DOT1AE_ALG_TYPE_SM4,    /**< [AT] Sm4 encrypt algorithm*/
    CTC_DOT1AE_ALG_TYPE_AES_MAX
};
typedef enum ctc_dot1ae_alg_type_e ctc_dot1ae_alg_type_t;


/**
 @brief Dot1ae encryption offset
*/
enum ctc_dot1ae_encrypt_offset_e
{
    CTC_DOT1AE_ENCRYPTION_OFFSET_0,    /**< [D2.TM.TMM.AT] Encrypt all user data*/
    CTC_DOT1AE_ENCRYPTION_OFFSET_30,   /**< [D2.TM.TMM.AT] Encrypt user data from offset 30*/
    CTC_DOT1AE_ENCRYPTION_OFFSET_50,   /**< [D2.TM.TMM.AT] Encrypt user data from offset 50*/
    CTC_DOT1AE_ENCRYPTION_OFFSET_NUM
};
typedef enum ctc_dot1ae_encrypt_offset_e ctc_dot1ae_encrypt_offset_t;

/**
 @brief Dot1ae secure channel direction
*/
enum ctc_dot1ae_sc_dir_e
{
    CTC_DOT1AE_SC_DIR_TX,     /**< [D2.TM.TMM.AT] TX SC */
    CTC_DOT1AE_SC_DIR_RX      /**< [D2.TM.TMM.AT] RX SC */
};
typedef enum ctc_dot1ae_sc_dir_e ctc_dot1ae_sc_dir_t;

/**
 @brief Dot1ae secure association flag
*/
enum ctc_dot1ae_sa_flag_e
{
    CTC_DOT1AE_SA_FLAG_NEXT_PN            = 0x00000001,      /**< [D2.TM.TMM.AT]If set, indicate it is valid */
    CTC_DOT1AE_SA_FLAG_KEY                = 0x00000002,      /**< [D2.TM.TMM.AT]If set, indicate it is valid */
    CTC_DOT1AE_SA_FLAG_ENCRYPTION         = 0x00000004,      /**< [D2.TM.TMM.AT]If set, indicate encryption option */
    CTC_DOT1AE_SA_FLAG_ICV_ERROR_ACTION   = 0x00000008,      /**< [D2]If set, indicate it is valid */
    CTC_DOT1AE_SA_FLAG_VALIDATEFRAMES     = 0x00000010       /**< [TM.TMM.AT]If set, validateframes is valid */

};
typedef enum ctc_dot1ae_sa_flag_e ctc_dot1ae_sa_flag_t;

/**
 @brief Dot1ae cipher suite
*/
enum ctc_dot1ae_cipher_suite_e
{
    CTC_DOT1AE_CIPHER_SUITE_GCM_AES_128,         /**< [D2.TM.TMM.AT] CIPHER SUITE GCM AES 128 */
    CTC_DOT1AE_CIPHER_SUITE_GCM_AES_256,         /**< [TM.TMM.AT] CIPHER SUITE GCM AES 256 */
    CTC_DOT1AE_CIPHER_SUITE_GCM_AES_XPN_128,     /**< [TM.TMM.AT] CIPHER SUITE GCM AES XPN 128 */
    CTC_DOT1AE_CIPHER_SUITE_GCM_AES_XPN_256,     /**< [TM.TMM.AT] CIPHER SUITE GCM AES XPN 256 */
    CTC_DOT1AE_CIPHER_SUITE_MAX
};
typedef enum ctc_dot1ae_cipher_suite_e ctc_dot1ae_cipher_suite_t;

/**
 @brief define validateframes mode
*/
enum ctc_dot1ae_validateframes_e
{
    CTC_DOT1AE_VALIDFRAMES_DISABLE,         /**< [TM.TMM.AT] validateframes disable */
    CTC_DOT1AE_VALIDFRAMES_CHECK,           /**< [TM.TMM.AT] validateframes check */
    CTC_DOT1AE_VALIDFRAMES_STRICT,          /**< [TM.TMM.AT] validateframes strict */
    CTC_DOT1AE_VALIDFRAMES_MAX
};
typedef enum ctc_dot1ae_validateframes_e ctc_dot1ae_validateframes_t;

/**
 @brief Dot1ae secure association
*/
struct ctc_dot1ae_sa_s
{
    uint32 upd_flag;                    /**< [D2.TM.TMM.AT] [rx/tx]update flag ctc_dot1ae_sa_flag_t*/
    uint8  an;                          /**< [D2.TM.TMM.AT] [rx/tx] Association Number*/
    uint64 next_pn;                     /**< [D2.TM.TMM.AT] [rx/tx] Packet Number, D2 max value is 0xffffffff*/
    uint64 lowest_pn;                   /**< [D2.TM.TMM.AT] [rx] [read only] Packet Number*/
    uint8  in_use;                      /**< [D2.TM.TMM.AT] [rx/tx][read only] if set,indicate the an is in use.*/
    uint8  key[CTC_DOT1AE_KEY_LEN];     /**< [D2.TM.TMM.AT] [rx/tx] key, 128 bits or 256 bits*/
    uint8  no_encryption;               /**< [D2.TM.TMM.AT][rx/tx] if set,indicate packet is unencrypted*/
    uint16 confid_offset;               /**< [D2.TM.TMM.AT][rx/tx] Encrypted packet confidentiality offset ,refer to ctc_dot1ae_encrypt_offset_t*/
    uint8  icv_error_action;            /**< [D2] [rx] icv check fail action, ctc_exception_type_t, valid when  CTC_DOT1AE_SA_FLAG_ICV_ERROR_ACTION is set*/
    uint8  cipher_suite;                /**< [TM.TMM.AT] refer to ctc_dot1ae_cipher_suite_t valid when  icv_check_disable is 0*/
    uint8  salt[CTC_DOT1AE_SALT_LEN];   /**< [TM.TMM.AT] [rx/tx] Salt for GCM_AES_XPN_128 and  GCM_AES_XPN_256, valid when  CTC_DOT1AE_SA_FLAG_KEY is set */
    uint32 ssci;                        /**< [TM.TMM.AT] [rx/tx] Short SCI for GCM_AES_XPN_128 and  GCM_AES_XPN_256, valid when  CTC_DOT1AE_SA_FLAG_KEY is set*/
    uint8 validateframes;               /**< [TM.TMM.AT] [rx] icv check mode, DISABLE, CHECK or STRICT*/
};
typedef struct ctc_dot1ae_sa_s ctc_dot1ae_sa_t;

/**
 @brief Dot1ae secure channel property
*/
enum ctc_dot1ae_sc_property_e
{
    CTC_DOT1AE_SC_PROP_AN_EN,               /**< [D2.TM.TMM.AT][tx/rx] Enable AN bitmap to channel  */
    CTC_DOT1AE_SC_PROP_NEXT_AN,             /**< [D2][tx] Enable NEXT AN channel (0~3) */
    CTC_DOT1AE_SC_PROP_INCLUDE_SCI,         /**< [D2.TM.TMM.AT] [tx] Transmit SCI in MacSec Tag*/
    CTC_DOT1AE_SC_PROP_SCI,                 /**< [D2.TM.TMM.AT] [tx] Secure Channel Identifier,64 bit.*/
    CTC_DOT1AE_SC_PROP_REPLAY_WINDOW_SIZE,  /**< [D2.TM.TMM.AT] [rx] Replay protect windows size*/
    CTC_DOT1AE_SC_PROP_REPLAY_PROTECT_EN,   /**< [D2.TM.TMM.AT] [rx] Replay protect enable or disable */
    CTC_DOT1AE_SC_PROP_SA_CFG,              /**< [D2.TM.TMM.AT] [tx/rx] configure SA Property,ext_data: ctc_dot1ae_sa_t*/
    CTC_DOT1AE_SC_PROP_PROTOCOL_MODE        /**< [AT] [tx/rx] Protocol type for CloudSec or Ipsec, "0" means fixed mode, "1" means flexible mode decided by unencrypted packet */
};
typedef enum ctc_dot1ae_sc_property_e ctc_dot1ae_sc_property_t;

/**
 @brief Dot1ae sc pn mode
*/
enum ctc_dot1ae_pn_mode_e
{
    CTC_DOT1AE_SC_PN_MODE_NONE,            /**< [TMM.AT][tx/rx] Means Using global config of pn/xpn mode*/
    CTC_DOT1AE_SC_PN_MODE,                 /**< [TMM.AT][tx/rx] Enable pn mode per sec-chan, it has higher priority than global config*/
    CTC_DOT1AE_SC_XPN_MODE                 /**< [TMM.AT][tx/rx] Enable xpn mode per sec-chan, it has higher priority than global config */
};
typedef enum ctc_dot1ae_pn_mode_e ctc_dot1ae_pn_mode_t;

/**
 @brief Dot1ae clear tag type
*/
enum ctc_dot1ae_clear_tag_type_e
{
    CTC_DOT1AE_CLEAR_TAG_SINGLE =1,            /**< [TMM] Means it will skip single vlan tag for decryption/encryption */
    CTC_DOT1AE_CLEAR_TAG_DOUBLE                /**< [TMM] Means it will skip double vlan tag for decryption/encryption */
};
typedef enum ctc_dot1ae_clear_tag_type_e ctc_dot1ae_clear_tag_type_t;

/**
 @brief Dot1ae secure channel
*/

/********************Centec Security Header construct*********************************
*   |---rsv1--|-old-pro-|------SrcCid------|----EcmpHash------|---rsv---|---SPI---|  *
*   | 63 -56  | 55 - 48 |      47 - 32     |	 31 - 16      | 15 - 9  |  8 - 0  |  *
*	|---------|---------|------------------|------------------|---------|---------|  *
*************************************************************************************/
struct ctc_dot1ae_sc_s
{
    uint32   chan_id;                /**< [D2.TM.TMM.AT] bind Dot1AE SC ID to port,value = 0 is unbind*/
    uint8    dir;                    /**< [D2.TM.TMM.AT] tx/rx*/
    uint8    property;               /**< [D2.TM.TMM.AT] ctc_dot1ae_sc_property_t */
    uint64   data;                   /**< [D2.TM.TMM.AT] Key Field data (uint64). */
    void*  ext_data;                 /**< [D2.TM.TMM.AT] Key Field extend data (void*). */
    uint8  is_p2mp;                  /**< [TMM.AT] If set, indicate it's P2MP channel */
    uint8  pn_mode;                  /**< [TMM.AT] PN or XPN mode, refer to  ctc_dot1ae_pn_mode_t*/
    uint8  clear_tag_en;             /**< [TMM] If set, indicate it will skip single/double vlan tag for decryption/encryption*/
    uint8  with_ctc_sh;              /**<[AT][tx] If set, means will take 8 bytes centec security header before sectag for encryption*/
};
typedef struct ctc_dot1ae_sc_s ctc_dot1ae_sc_t;

/**
 @brief mirrored packet type on dot1ae port
*/
enum ctc_dot1ae_port_mirror_mode_e
{
    CTC_DOT1AE_PORT_MIRRORED_MODE_PLAIN_TEXT = 0,   /**< [D2.TM.TMM.AT] mirror plain pkt on dot1ae enabled port*/
    CTC_DOT1AE_PORT_MIRRORED_MODE_ENCRYPTED = 1     /**< [D2.TM] mirror encrypted pkt on dot1ae enabled port*/
};
typedef enum ctc_dot1ae_port_mirror_mode_e ctc_dot1ae_port_mirror_mode_t;

/**
 @brief key type data structure for Dot1AE global
*/
struct ctc_dot1ae_key_type_cfg_s
{
    uint8 packet_type;          /**< [AT] packet type, refer to ctc_dot1ae_packet_type_t*/
    uint8 key_type;             /**< [AT] key type, refer to ctc_dot1ae_key_type_t */
    uint8 dir;                  /**< [AT] Direction, refer to ctc_direction_t */
};
typedef struct ctc_dot1ae_key_type_cfg_s ctc_dot1ae_key_type_cfg_t;


/**
 @brief Security data structure for Dot1AE global
*/
struct ctc_dot1ae_glb_cfg_s
{
    uint64 tx_pn_thrd;                   /**< [D2.TM.TMM.AT] Dot1AE Encrypt PN Threshold, D2 max value is 0xffffffff*/
    uint64 rx_pn_thrd;                   /**< [D2.TM.TMM.AT] Dot1AE Decrypt PN Threshold, D2 max value is 0xffffffff*/
    uint64 tx_xpn_thrd;                  /**< [TMM.AT] Dot1AE Encrypt PN Threshold*/
    uint64 rx_xpn_thrd;                  /**< [TMM.AT] Dot1AE Decrypt PN Threshold*/
    uint8  dot1ae_port_mirror_mode;      /**< [D2.TM.TMM.AT] The Dot1AE port enable mirroring or random-log,
                                            which data packets (plaintext or ciphertext) will be mirrored. refer to ctc_dot1ae_port_mirror_mode_t ,for TMM only plaintext could been mirrored because of no loop*/
    uint8  tx_pn_overflow_action;        /**< [TM] Dot1ae pn overflow action, refer to ctc_exception_type_t.*/
    uint8  is_xpn;                       /**< [TM.TMM.AT] Dot1AE xpn mode, cipher suite must be set to GCM-AES-XPN-128 or GCM-AES-XPN-256*/
    uint8  algorithm_type;               /**< [AT] Dot1AE encrypt algorithm type, refer to ctc_dot1ae_encrypt_algorithm_type_t*/
    uint8  ctc_sh_mode;                  /**< [AT] If set, means in centec security header, the SrcCid come from reserved field in vXlan or GRE packet, otherwise from ACL*/
    ctc_dot1ae_key_type_cfg_t key_type;  /**< [AT] set key type according to packet type */
};
typedef struct ctc_dot1ae_glb_cfg_s ctc_dot1ae_glb_cfg_t;

struct ctc_dot1ae_an_stats_s
{
    uint64 out_pkts_protected;      /**< [TM.TMM.AT] protected packet count*/
    uint64 out_pkts_encrypted;      /**< [TM.TMM.AT] encrypted packet count*/
    uint64 in_pkts_ok;              /**< [TM.TMM.AT] valid packet count*/
    uint64 in_pkts_unchecked;       /**< [TM.TMM.AT] unchecked packet count*/
    uint64 in_pkts_delayed;         /**< [TM.TMM.AT] delayed packet count*/
    uint64 in_pkts_invalid;         /**< [TM.TMM.AT] invalid packet count*/
    uint64 in_pkts_not_valid;       /**< [TM.TMM.AT] not valid packet count*/
    uint64 in_pkts_late;            /**< [TM.TMM.AT] late packet count*/
    uint64 out_pkts_sa_not_inuse;   /**< [TMM.AT] packet not using sa packet count*/

    /*In p2mp mode,the following statsics are bound the port, so itcan be got through
    the API ctc_port_get_direction_property(CTC_PORT_DIR_PROP_DOT1AE_STATS) */
    uint64 in_pkts_not_using_sa;    /**< [TM.TMM.AT] not using sa packet count*/
    uint64 in_pkts_unused_sa;       /**< [TM.TMM.AT] unused sa packet count*/
    uint64 in_pkts_badtag;          /**< [TMM.AT] badtag packet count*/
    uint64 in_octets_decrypted;     /**< [TMM.AT] decrypted octets count*/
    uint64 in_octets_validated;     /**< [TMM.AT] validated octets count, not decrypted but passed icvcheck*/
    uint64 out_pkts_toolong;        /**< [TMM.AT] packet lenth too long count*/
    uint64 out_pkts_untagged;       /**< [TMM.AT] packet without macsectag count*/
    uint64 out_octets_encrypted;    /**< [TMM.AT] encrypted octets count*/
    uint64 out_octets_protected;    /**< [TMM.AT] validated octets count, not encrypted  but icvcheck*/
    uint64 out_pkts_uncontrol_port; /**< [AT] controlled port disable packet count */

    /* only for AT, per port */
    uint64 in_pkts_discard;         /**< [AT] ingress packets discarded by XSec engine, count per port*/
    uint64 out_pkts_discard;        /**< [AT] egress packets discarded by XSec engine, count per port*/
};
typedef struct ctc_dot1ae_an_stats_s ctc_dot1ae_an_stats_t;



/**
 @brief  Define dot1ae stats
*/
struct ctc_dot1ae_stats_s
{
    ctc_dot1ae_an_stats_t an_stats[4];      /**< [TM.TMM.AT] Dot1AE stats per channel*/
    uint64 in_pkts_no_sci;                  /**< [TM] Dot1AE global stats*/
    uint64 in_pkts_unknown_sci;             /**< [TM] Dot1AE global stats*/
};
typedef struct ctc_dot1ae_stats_s  ctc_dot1ae_stats_t;


/**
 @brief Dot1ae event
*/
enum ctc_dot1ae_event_type_e
{
    CTC_DOT1AE_EVENT_PN_OVER_FLOW   = 0x00001,         /**< [TMM.AT] PN is greater than Threshold  */
	CTC_DOT1AE_EVENT_AN_SWITCH      = 0x00002,         /**< [AT] Auto hardware switch AN when TX PN is greater than Threshold  */
};
typedef enum ctc_dot1ae_event_type_e  ctc_dot1ae_event_type_t;

/*
 @brief   Define dot1ae defect information entry
*/
struct ctc_dot1ae_event_entry_s
{
    uint32   chan_id;                        /**< [TMM.AT] Bind Dot1AE SC ID to port */
    uint8    sa_inuse;                       /**< [TMM.AT] Association Number in use */
    uint8    event_bmp;                      /**< [TMM.AT] Dot1ae Interrupt event bitmap, refer to ctc_dot1ae_event_type_t */
    uint8    dir;                            /**< [TMM.AT] tx/rx*/
    uint8   rsv[1];
};
typedef struct ctc_dot1ae_event_entry_s ctc_dot1ae_event_entry_t;

/**
 @brief Define event data structure
*/
struct ctc_dot1ae_event_s
{
    uint16 valid_num;                                               /**< [TMM.AT] Indicated valid event entry num */
    uint8  resv0[2];
    ctc_dot1ae_event_entry_t event_entry[CTC_DOT1AE_EVENT_MAX_NUM]; /**< [TMM.AT] Event entry ,refer to ctc_oam_event_entry_t */
};
typedef struct ctc_dot1ae_event_s ctc_dot1ae_event_t;


enum ctc_dot1ae_packet_type_e
{
    CTC_DOT1AE_PKT_NONE,
    CTC_DOT1AE_PKT_MACSEC,               /**< [AT] [Rx][Tx] use to decrypt MACSEC packet, or use to encrypt packet to MACSEC packet */
    CTC_DOT1AE_PKT_CTCSEC_IPV4,          /**< [AT] [Rx] use to decrypt CTCsec IPv4 packet */
    CTC_DOT1AE_PKT_CTCSEC_IPV6,          /**< [AT] [Rx] use to decrypt CTCsec IPv6 packet */
    CTC_DOT1AE_PKT_CLOUDSEC_IPV4,        /**< [AT] [Rx] use to decrypt cloudsec IPv4 packet */
    CTC_DOT1AE_PKT_CLOUDSEC_IPV6,        /**< [AT] [Rx] use to decrypt cloudsec IPv6 packet */
    CTC_DOT1AE_PKT_CTCSEC_IPV4_CTCSH,    /**< [AT] [Rx][Tx] use to decrypt CTCsec IPv4 packet with ctc shim header, or use to encrypt IPv4 packet with ctc shim header */
    CTC_DOT1AE_PKT_CTCSEC_IPV6_CTCSH,    /**< [AT] [Rx][Tx] use to decrypt CTCsec IPv6 packet with ctc shim header, or use to encrypt IPv6 packet with ctc shim header */
    CTC_DOT1AE_PKT_CLOUDSEC_IPV4_CTCSH,  /**< [AT] [Rx][Tx] use to decrypt cloudsec IPv4 packet with ctc shim header, or use to encrypt IPv4 packet with ctc shim header */
    CTC_DOT1AE_PKT_CLOUDSEC_IPV6_CTCSH,  /**< [AT] [Rx][Tx] use to decrypt cloudsec IPv6 packet with ctc shim header, or use to encrypt IPv6 packet with ctc shim header */
    CTC_DOT1AE_PKT_IPV4,                 /**< [AT] [Rx][Tx] use for IPv4 packet for bypass decryption, or use to encrypt IPv4 packet*/
    CTC_DOT1AE_PKT_IPV6,                 /**< [AT] [Rx][Tx] use for IPv6 packet for bypass decryption, or use to encrypt IPv6 packet*/
    CTC_DOT1AE_PKT_OTHERS,               /**< [AT] [Rx][Tx] use for neither IPv4 nor IPv6 packet for bypass decryption,, [Tx] or use for neither IPv4 nor IPv6 packet encryption */
    CTC_DOT1AE_PKT_MAX
};
typedef enum ctc_dot1ae_packet_type_e ctc_dot1ae_packet_type_t;

struct ctc_dot1ae_hash_sel_s
{
    uint32 gport;                                             /**< [AT] Global port*/
    uint8 packet_type;                                        /**< [AT] decryption or encryption packet type, refer to ctc_dot1ae_packet_type_t*/
    uint8 dir;                                                /**< [AT] Direction, refer to ctc_direction_t */
    uint8 rsv[2];
    ctc_field_key_t* field_key_list;                          /**< [AT] hash key field list, refer to ctc_field_key_type_t*/
    uint32 field_cnt;                                      /**< [AT] field count of field key list */
};
typedef struct ctc_dot1ae_hash_sel_s ctc_dot1ae_hash_sel_t;


enum ctc_dot1ae_key_type_e
{
    CTC_DOT1AE_KEY_NONE,
    CTC_DOT1AE_KEY_L2,                     /**< [AT][Rx] use L2 fields to generate hash key, use to bypass decryption as plain text */
    CTC_DOT1AE_KEY_MACSEC,                 /**< [AT][Tx/Rx] use MacSec or L2 fields to generate hash key */
    CTC_DOT1AE_KEY_IPV4,                   /**< [AT][Tx/Rx] use ipv4 & udp fields to generate hash key */
    CTC_DOT1AE_KEY_IPV6,                   /**< [AT][Tx/Rx] use ipv6 & udp fields to generate hash key */
    CTC_DOT1AE_KEY_SPI,                    /**< [AT][Tx/Rx] use SPI fields to generate hash key */
    CTC_DOT1AE_KEY_MAX
};
typedef enum ctc_dot1ae_key_type_e ctc_dot1ae_key_type_t;

/**
 @brief Define dot1ae entry structure
*/
struct ctc_dot1ae_entry_s
{
    uint32 entry_id;                   /**< [AT] Dot1ae entry id */

    uint8  key_type;                   /**< [AT] Dot1ae key type,refer to ctc_dot1ae_key_type_t*/
    uint8  dir;                        /**< [AT] Direction, refer to ctc_direction_t */

    ctc_field_key_t* p_field_key;      /**< [AT] array of key field which is used to generate key */
    uint32 field_cnt;               /**< [AT] count of key field array */

    uint32 chan_id;                    /**< [AT] Dot1ae chan id */
};
typedef struct ctc_dot1ae_entry_s ctc_dot1ae_entry_t;


/**@} end of @defgroup  dot1ae DOT1AE */

#ifdef __cplusplus
}
#endif

#endif

